#include <iostream>
#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "comm.h"

bool MakeFifo()//创建好了管道文件，接下来实现管道通信只需要让不同的进程同时对该文件各自进行读写
{
    int n = mkfifo(FILENAME, 0666);//创建管道文件，成功返回0，不成功返回-1并且设置错误码
    if(n < 0)
    {
        std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;
        return false;
    }

    std::cout << "mkfifo success... read" << std::endl;
    return true;
}

int main()
{
Start:
    int rfd = open(FILENAME, O_RDONLY);
    if(rfd < 0)//如果打开失败
    {
        std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;
        if(MakeFifo()) goto Start;//如果创建成功，就重新打开
        else return 1;
    }
    std::cout << "open fifo success..." << std::endl;//管道需要两个进程同时打开，如果写端没有打开，那么这个进程会阻塞在创建管道那里，
    //而不会打开这个管道，可以分两个终端分别运行两个可执行程序

    char buffer[1024];//因为管道是面向字节流的，所以什么数据类型都可以写（大小不同）
    while(true)
    {
        ssize_t s = read(rfd, buffer, sizeof(buffer)-1);
        if(s > 0)
        {
            buffer[s] = 0;//让该缓冲区以“\0”结尾，表明是一个字符串
            std::cout << "Client say# " << buffer << std::endl;
        }
        else if(s == 0)//返回0说明写端关闭了，那么接下来应该把读端也关闭，不然就会一直阻塞
        {
            std::cout << "client quit, server quit too!" << std::endl;
            break;
        }
    }

    close(rfd);
    std::cout << "close fifo success..." << std::endl;

    return 0;
}